package com.imay.live.manager;

import android.app.Activity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.imay.base.activity.BaseActivity;
import com.imay.base.helper.ActivityHelper;
import com.imay.base.util.MD5Util;
import com.imay.cocos.IMayCocos;
import com.imay.live.IMApplication;
import com.imay.live.R;
import com.imay.live.activity.BaseUserActivity;
import com.imay.live.activity.MainActivity2;
import com.imay.live.activity.family.FamilyCreateActivity;
import com.imay.live.activity.family.helper.NimLogin;
import com.imay.live.activity.user.LoginActivity;
import com.imay.live.activity.user.UserActivity;
import com.imay.live.analytics.MobclickAgent;
import com.imay.live.cache.UserInfoCache;
import com.imay.live.fragment.room.LevelUpgradeFragment2;
import com.imay.live.fragment.user.MainUserListener;
import com.imay.live.helper.CallBack;
import com.imay.live.helper.DialogFragmentHelper;
import com.imay.live.helper.EventHelper;
import com.imay.live.helper.PreferenceHelper;
import com.imay.live.helper.ShareNoticeHelper;
import com.imay.live.helper.ThreadManager;
import com.imay.live.helper.UrlHelper;
import com.imay.live.model.FamilyUserInfo;
import com.imay.live.model.ShortLiveInfoModel;
import com.imay.live.model.UserInfoModel;
import com.imay.live.model.UserQQModel;
import com.imay.live.model.UserWBModel;
import com.imay.live.model.UserWechatModel;
import com.imay.live.proto.ErrorResult;
import com.imay.live.proto.MessageId;
import com.imay.live.proto.ProtoResult;
import com.imay.live.proto.Result;
import com.imay.live.proto.ResultCode;
import com.imay.live.proto.SocketState;
import com.imay.live.proto.UserToken;
import com.imay.live.proto.helper.ProtoCallBack;
import com.imay.live.proto.helper.ProtoHttpFactory;
import com.imay.live.proto.helper.ProtoRequestHelper;
import com.imay.live.proto.helper.ProtoSocketFactory;
import com.imay.live.proto.room.RoomLiveBlockNotify;
import com.imay.live.proto.user.UserUpdataLvNotify;
import com.imay.live.utils.ToastUtil;
import com.imay.tbas_api.IMYScheduler;
import com.imay.tbas_api.IMYTBASObject;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.shareboard.SnsPlatform;

import java.util.ArrayList;

import static com.imay.live.cache.UserInfoCache.saveUserInfo;
import static com.imay.live.proto.ResultCode.CodeSuccess;

/**
 * Created by jeaman on 2017/3/31.
 */

public class AccountManager {
    private int loginWay;

    public final static String QQ_KEY = "1105650145";

    private final static int LOGIN_NONE = 0;
    private final static int LOGIN_PHONE = 1;
    private final static int LOGIN_QQ = 2;
    private final static int LOGIN_WEIXIN = 3;
    private final static int LOGIN_WEIBO = 4;

    private final static int LOGIN_STATE_IDE = 0;
    private final static int LOGIN_STATE_ING = 1;
    private final static int LOGIN_STATE_SUCCESS = 2;
    private final static int LOGIN_STATE_ERROR = 3;
    private final static int LOGIN_STATE_KICKOUT = 4;
    private final static int LOGIN_STATE_TOKEN_TIME_OUT = 5; // 存放的token信息超时

    private static AccountManager instance;
    private UserToken mUserToken;
    private int mLoginState = LOGIN_STATE_IDE;

    private boolean firstLogin = false;

    private IMYTBASObject mSocketStateNotify;
    private IMYTBASObject mSocketNotify;

    public static final int TOKENTCPTAG = 101;

    private SHARE_MEDIA[] list = {SHARE_MEDIA.QQ, SHARE_MEDIA.SINA, SHARE_MEDIA.WEIXIN};

    public ArrayList<SnsPlatform> platforms = new ArrayList<SnsPlatform>();


    private AccountManager() {
        mUserToken = JSON.parseObject(PreferenceHelper.getInstance().getUserToken(), UserToken.class);

        setLoginWay(LOGIN_NONE);

        //监听socket状态
        mSocketStateNotify = new IMYTBASObject(false);
        mSocketStateNotify.stringCommand = "SOCK_STATE";
        mSocketStateNotify.setDataResultListener(new IMYTBASObject.OnDataResultListener() {
            @Override
            public void onCommandTaskSuccess(IMYTBASObject object) {
                SocketState socketState = JSON.parseObject(object.stringData, SocketState.class);
                if (socketState.getState() == 0) {
                    autoLogin(null);    //socket连接成功，重新登录
                }
            }
        });
        mSocketStateNotify.addEventListenWithTBASObject();

        //监听socket
        mSocketNotify = new IMYTBASObject(false);
        mSocketNotify.stringCommand = "SOCK_NOTIFY";
        mSocketNotify.setDataResultListener(new IMYTBASObject.OnDataResultListener() {
            @Override
            public void onCommandTaskSuccess(IMYTBASObject object) {
                IMayCocos.SDK2Cocos_network_Notify(object.socket_msg_id, object.socket_content);
                processSocketNotify(object.socket_msg_id, object.socket_content);
            }
        });
        mSocketNotify.addEventListenWithTBASObject();

        initPlatforms();
    }

    private void initPlatforms() {
        platforms.clear();
        for (SHARE_MEDIA e : list) {
            if (!e.toString().equals(SHARE_MEDIA.GENERIC.toString())) {
                platforms.add(e.toSnsPlatform());
            }
        }
    }

    public ArrayList<SnsPlatform> getPlatforms() {
        return platforms;
    }

    private void processSocketNotify(int msgId, String content) {
        switch (msgId) {
            case MessageId.accountKickoutNotify: //互斥通知
                ThreadManager.post(
                        new Runnable() {
                            @Override
                            public void run() {
                                clear();
                                kickoutAccount();
                            }
                        }
                );
                break;
            case MessageId.roomLiveBlockNotify: //封禁通知
                RoomLiveBlockNotify roomLiveBlockNotify = JSON.parseObject(content, RoomLiveBlockNotify.class);
                if (roomLiveBlockNotify.uid == getUid() && roomLiveBlockNotify.LockType == 3) {    //封号
                    logout(null);
                    MainActivity2.startActivityForLogout(ActivityHelper.getInstance().getCurrentActivity(), BaseUserActivity.OPEN_USER_FRAGMENT);
                    ThreadManager.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtil.show(IMApplication.getInstance(), R.string.tips_forbidden_account);
                        }
                    });
                }
                break;
            case MessageId.shortLiveFeedNotify: {//自动发布动态通知
                final ShortLiveInfoModel shortLiveInfoModel = JSON.parseObject(content, ShortLiveInfoModel.class);
                final String title;
                UserInfoModel userInfoModel = UserInfoCache.getUserInfo();
                if (userInfoModel != null && userInfoModel.getUser() != null) {
                    title = IMApplication.getInstance().getResources().getString(R.string.short_live_share_title, userInfoModel.getUser().getNick());
                } else {
                    title = shortLiveInfoModel.getChallengeContent();
                }
                ThreadManager.post(new Runnable() {
                    @Override
                    public void run() {
                        ShareNoticeHelper.getInstance().show(UrlHelper.getShareShortLiveUrl(shortLiveInfoModel.getShortLiveId()), UrlHelper.getVideoThumbUrl(shortLiveInfoModel.getVideoUrl()), title, shortLiveInfoModel.getChallengeContent());
                    }
                });
                EventHelper.postUpdateShortLiveProfile();
                break;
            }
        }
    }

    public synchronized static AccountManager getInstance() {
        if (instance == null) {
            instance = new AccountManager();
        }
        return instance;
    }

    private void setLoginState(int state) {
        mLoginState = state;
    }

    public long getUid() {
        if (mUserToken != null) {
            return mUserToken.uid;
        }
        return 0;
    }

    public String getAccessCode() {
        if (mUserToken != null) {
            return mUserToken.accessCode;
        }
        return "";
    }

    public boolean isLogined() {
        return mLoginState == LOGIN_STATE_SUCCESS;
    }


    /**
     * token过期
     *
     * @return
     */
    public boolean isTokenTimeOut() {
        return mLoginState == LOGIN_STATE_TOKEN_TIME_OUT;
    }

    //是否登录过
    public boolean hasLoginBefore() {
        if (mUserToken != null) {
            if (mUserToken.expireAt * 1000 > System.currentTimeMillis()) {
                return true;
            } else { // 判断是否已经过期
                setLoginState(LOGIN_STATE_TOKEN_TIME_OUT);
            }
        }
        return false;
    }

    // 退出登录
    public void logout(ProtoCallBack callBack) {
        // 清除数据
        DataSetManager.clearData();
        setLoginState(LOGIN_STATE_IDE);
        UserInfoCache.clearUserInfo();
        mUserToken = null;
        FamilyAccountManager.getInstance().clear();
        NimLogin.getInstance().logout();
        firstLogin = false;
        PreferenceHelper.getInstance().cleanUserToken();
        MobclickAgent.onProfileSignOff();
        ProtoRequestHelper.task(ProtoSocketFactory.requestAccountLogout()).setTag(this.hashCode()).request(callBack);
    }

    // 自动登录
    public boolean autoLogin(CallBack callBack) {
        setLoginState(LOGIN_STATE_IDE);
        if (hasLoginBefore()) {
            loginByTokenTCP(mUserToken, callBack);
            ProtoRequestHelper.task(ProtoSocketFactory.requestAccountReportDelay()).request(null);
            return true;
        }
        return false;
    }

    private void loginByTokenTCP(UserToken userToken, final CallBack callBack) {
        setLoginState(LOGIN_STATE_ING);
        String commend = ProtoRequestHelper.task(ProtoSocketFactory.requestAuthSession(userToken.uid, userToken.accessCode)).setTag(TOKENTCPTAG).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                setLoginState(LOGIN_STATE_SUCCESS);
                EventHelper.postLoginSuccess(); //发送登录成功通知
                //cocos设置uid
                IMayCocos.setCocosUserInfo(getUid());

                // 友盟统计登录
                analyticsLogin();
                loaUserInfo(callBack);
                FamilyAccountManager.getInstance().loadFamilyUserInfo(true);
                FamilyAccountManager.getInstance().loadExpConfig();
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                setLoginState(LOGIN_STATE_ERROR);
                if (callBack != null) {
                    callBack.onError(code, message);
                }
            }
        });
    }


    /**
     * 友盟统计登录方式
     */
    private void analyticsLogin() {
        if (AccountManager.getInstance().getUid() != 0) {
            if (loginWay == LOGIN_PHONE) {
                MobclickAgent.onProfileSignIn(Long.toString(AccountManager.getInstance().getUid()));
            } else if (loginWay == LOGIN_QQ) {
                MobclickAgent.onProfileSignIn("QQ", Long.toString(AccountManager.getInstance().getUid()));
            } else if (loginWay == LOGIN_WEIBO) {
                MobclickAgent.onProfileSignIn("WB", Long.toString(AccountManager.getInstance().getUid()));
            } else if (loginWay == LOGIN_WEIXIN) {
                MobclickAgent.onProfileSignIn("WX", Long.toString(AccountManager.getInstance().getUid()));
            }
        }
    }

    // 获取用户信息
    public void loaUserInfo(final CallBack callBack) {
        if (getUid() == 0) {
            return;
        }
        ProtoRequestHelper.task(ProtoHttpFactory.getUserInfo(getUid())).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                Result<UserInfoModel> result = JSON.parseObject(data, new TypeReference<Result<UserInfoModel>>() {
                }.getType());
                if (result.result == CodeSuccess) {
                    saveUserInfo(result.data);
                }
                if (callBack != null) {
                    callBack.onSuccess();
                }
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                if (callBack != null) {
                    callBack.onSuccess();
                }
            }
        });
    }

    //http登录成功
    private void onHttpLoginSuccess(String tokenJson, CallBack callBack) {
        Result<UserToken> result = JSON.parseObject(tokenJson, new TypeReference<Result<UserToken>>() {
        }.getType());
        if (result.result == CodeSuccess && result.data != null) {
            mUserToken = result.data;
            if (!TextUtils.isEmpty(result.data.firstLogin)) {
                firstLogin = result.data.firstLogin.equalsIgnoreCase("T") ? true : false;
            }
            PreferenceHelper.getInstance().saveUserToken(JSON.toJSONString(mUserToken));
            loginByTokenTCP(mUserToken, callBack);
            ProtoRequestHelper.task(ProtoSocketFactory.requestAccountReportDelay()).request(null);
        } else {
            callBack.onError(result.result, result.errorDesc);
        }
    }

    //用户名密码登录
    public void loginByPasswordHttp(int phoneCountry, long phone, String secret, final CallBack callBack) {
        ProtoRequestHelper.task(ProtoHttpFactory.requestLogin(phoneCountry, phone, secret)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String stringCommand, String data) {
                setLoginWay(LOGIN_PHONE);
                onHttpLoginSuccess(data, callBack);
            }

            @Override
            public void onRequestError(String stringCommand, int code, String message) {
                setLoginWay(LOGIN_NONE);
                if (callBack != null) {
                    callBack.onError(code, message);
                }
            }
        });
    }

    // 手机注册
    public void registerPhone(final int phoneCountry, final long phone, String verifyCode, final String secret, String nick, String imgHead, final CallBack callBack) {
        ProtoRequestHelper.task(ProtoHttpFactory.requestCreatePhone(phoneCountry, phone, verifyCode, secret, nick, imgHead)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                onHttpLoginSuccess(data, callBack);
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                if (code == ResultCode.CodeAccountPhoneRegisted) { // 改手机号已经注册
                    loginByPasswordHttp(phoneCountry, phone, secret, callBack);
                } else {
                    if (callBack != null) {
                        callBack.onError(code, message);
                    }
                }
            }
        });
    }

    // QQ登录
    public void loginByQQ(final String qqString, final CallBack callBack) {
        UserQQModel qqModel = JSON.parseObject(qqString, UserQQModel.class);
        ProtoRequestHelper.task(ProtoHttpFactory.loginByQQ(qqModel.getOpenid(), qqModel.getUnionid(), QQ_KEY, qqModel.getAccess_token())).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String stringCommand, String data) {
                setLoginWay(LOGIN_QQ);
                onHttpLoginSuccess(data, callBack);
            }

            @Override
            public void onRequestError(String stringCommand, int code, String message) {
                setLoginWay(LOGIN_NONE);
                if (callBack != null) {
                    callBack.onError(code, message);
                }
            }
        });
    }

    // 微信登录
    public void loginByWechat(final String wechatString, final CallBack callBack) {
        UserWechatModel wechatModel = JSON.parseObject(wechatString, UserWechatModel.class);
        ProtoRequestHelper.task(ProtoHttpFactory.loginByWechat(wechatModel.getOpenid(), wechatModel.getUnionid(), wechatModel.getAccess_token())).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String stringCommand, String data) {
                setLoginWay(LOGIN_WEIXIN);
                onHttpLoginSuccess(data, callBack);
            }

            @Override
            public void onRequestError(String stringCommand, int code, String message) {
                setLoginWay(LOGIN_NONE);
                if (callBack != null) {
                    callBack.onError(code, message);
                }
            }
        });
    }

    // 微博登录
    public void loginByWB(final String WBstring, final CallBack callBack) {
        UserWBModel wbModel = JSON.parseObject(WBstring, UserWBModel.class);
        String accessCode = wbModel.getAccessToken();
        if (TextUtils.isEmpty(accessCode)) {
            accessCode = wbModel.getAccess_token();
        }
        ProtoRequestHelper.task(ProtoHttpFactory.loginByWB(wbModel.getUid(), accessCode)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String stringCommand, String data) {
                setLoginWay(LOGIN_WEIBO);
                onHttpLoginSuccess(data, callBack);
            }

            @Override
            public void onRequestError(String stringCommand, int code, String message) {
                setLoginWay(LOGIN_NONE);
                if (callBack != null) {
                    callBack.onError(code, message);
                }
            }
        });
    }


    public UserToken getToken() {
        return mUserToken;
    }

    /**
     * 修改密码
     *
     * @param phone
     * @param oldPassword
     * @param newPassword
     * @param callBack
     */
    public void changePassword(String phone, String oldPassword, String newPassword, final ProtoCallBack callBack) {
        String oldSecret = MD5Util.getMD5(phone + oldPassword);
        String newSecret = MD5Util.getMD5(phone + newPassword);
        ProtoRequestHelper.task(ProtoHttpFactory.changePassword(oldSecret, newSecret)).setTag(this.hashCode()).request(callBack);
    }

    public void clear() {
        mUserToken = null;
    }

    /**
     * 互斥账号
     */
    public void kickoutAccount() {
        setLoginState(LOGIN_STATE_KICKOUT);
        if (!ActivityHelper.getInstance().isBackground()) { // 是否后台
            final Activity activity = ActivityHelper.getInstance().getCurrentActivity();
            if (activity != null && (activity instanceof BaseActivity)) {
                final BaseActivity baseActivity = (BaseActivity) activity;
                if (baseActivity instanceof MainUserListener) {
                    if (((MainUserListener) baseActivity).isUserShow()) {
                        return;
                    }
                }
                if (baseActivity instanceof LoginActivity) {
                    return;
                }
                if (loginWay != LOGIN_PHONE) {
                    DialogFragmentHelper.showTipsDialog(baseActivity.getSupportFragmentManager(), baseActivity.getString(R.string.str_login_orther), false, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            logout(null);
                            ProtoRequestHelper.cancelAllRequest();
                            IMayCocos.logout();
                            startLogin(baseActivity);
                        }
                    });
                } else {
                    DialogFragmentHelper.showConfirmDialog(baseActivity.getSupportFragmentManager(), null, baseActivity.getString(R.string.str_login_orther), baseActivity.getString(R.string.str_login_relogin_buttom), baseActivity.getString(R.string.str_login_relogin_out), false, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            CallBack call = new CallBack() {
                                @Override
                                public void onSuccess() {
                                    DialogFragmentHelper.closeLoadingDialog(baseActivity.getSupportFragmentManager());
                                    ToastUtil.showImg(baseActivity, baseActivity.getString(R.string.str_login_success), R.mipmap.jiaohutishidagou_3x, 200);
                                }

                                @Override
                                public void onError(int code, String message) {
                                    DialogFragmentHelper.closeLoadingDialog(baseActivity.getSupportFragmentManager());
                                    ToastUtil.showImg(baseActivity, ErrorResult.getString(baseActivity, code), R.mipmap.jiaohutishidaxia_3x, 200);
                                    logout(null);
                                    ProtoRequestHelper.cancelAllRequest();
                                    startLogin(baseActivity);
                                }
                            };

                            switch (loginWay) {
                                case LOGIN_PHONE:
                                    IMYScheduler.getInstance().stopSocketService();
                                    IMYScheduler.getInstance().startSocketService();
                                    final int local = PreferenceHelper.getInstance().getPhoneCountry();
                                    final String phone = PreferenceHelper.getInstance().getPhone();
                                    final String secret = PreferenceHelper.getInstance().getSec();
                                    if (local != -1 && !TextUtils.isEmpty(phone) && !TextUtils.isEmpty(secret)) {
                                        try {
                                            int l = local;
                                            long p = Long.parseLong(phone);
                                            DialogFragmentHelper.showLoadingDialog(baseActivity.getSupportFragmentManager(), baseActivity.getString(R.string.str_login_loading));
                                            loginByPasswordHttp(l, p, secret, call);
                                        } catch (Exception e) {
                                            startLogin(baseActivity);
                                        }
                                    } else {
                                        startLogin(baseActivity);
                                    }
                                    break;
                            }
                        }
                    }, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            logout(null);
                            ProtoRequestHelper.cancelAllRequest();
                            IMayCocos.logout();
                            startLogin(baseActivity);
                        }
                    });
                }
            }
        } else {
            ActivityHelper.getInstance().finishAllActivity();
        }
    }

    /**
     * 登录失效
     */
    public void loginLoseEfficacy() {
        if (!ActivityHelper.getInstance().isBackground()) { // 是否后台
            final Activity activity = ActivityHelper.getInstance().getCurrentActivity();
            if (activity != null
                    && (activity instanceof BaseActivity)) {
                final BaseActivity baseActivity = (BaseActivity) activity;
                if (baseActivity instanceof MainUserListener) {
                    if (((MainUserListener) baseActivity).isUserShow()) {
                        return;
                    }
                }
                if (baseActivity instanceof LoginActivity) {
                    return;
                }
                DialogFragmentHelper.showTipsDialog(baseActivity.getSupportFragmentManager(), baseActivity.getString(R.string.str_login_lose), false, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        logout(null);
                        if (!AccountManager.getInstance().isLogined()) {
                            // 注销用户失效通知，下次等用户进去MainActivity
                            MessageManager.getInstance().unregisterLoginLoseListener();
                        }
                        ProtoRequestHelper.cancelAllRequest();
                        IMayCocos.logout();
                        startLogin(baseActivity);
                    }
                });
            }
        }
    }

    /**
     * 等级提升
     */
    public void levelUpgrade(String content) {
        if (!ActivityHelper.getInstance().isBackground()) { // 是否后台
            final Activity activity = ActivityHelper.getInstance().getCurrentActivity();
            if (activity != null && (activity instanceof BaseActivity)) {
                final UserUpdataLvNotify updataLvNotify = JSON.parseObject(content, UserUpdataLvNotify.class);
                final BaseActivity baseActivity = (BaseActivity) activity;
                if (updataLvNotify.IsUpgrade) {
                    ThreadManager.post(new Runnable() {
                        @Override
                        public void run() {
                            DialogFragmentHelper.showDialogFragment(baseActivity.getSupportFragmentManager(), LevelUpgradeFragment2.newInstance(updataLvNotify.LvType == 2, updataLvNotify.Lv));
                        }
                    });
                }
            }
        }
    }

    private void setLoginWay(int way) {
        loginWay = way;
    }


    private void startLogin(final BaseActivity baseActivity) {
        ThreadManager.postDelayed(ThreadManager.THREAD_UI, new Runnable() {
            @Override
            public void run() {
                IMYScheduler.getInstance().stopSocketService();
                IMYScheduler.getInstance().startSocketService();
                MainActivity2.startActivityForLogout(baseActivity, BaseUserActivity.OPEN_USER_FRAGMENT);
                baseActivity.finish();
            }
        }, 1000);
    }

    public boolean isMyself(long targetUid) {
        if (mUserToken != null) {
            return targetUid == mUserToken.uid;
        }
        return false;
    }
}
